﻿using System;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Collections.Generic;

namespace WeiboPlus.Models
{
    [Table(Name = "sns_status")]
    public class SNSStatus : NotificationObject, IEquatable<SNSStatus>, WeiboPlus.Models.IPageCount
    {
        [Column(Name = "account_id", IsPrimaryKey = true)]
        int _accountID;
        EntityRef<SNSAccount> _account;
        public SNSAccount Account
        {
            get
            {
                return _account.Entity;
            }
            set
            {
                RaisePropertyChanging("Account");
                _account.Entity = value;
                if (value != null)
                {
                    _accountID = value.AccountID;
                }
                RaisePropertyChanged("Account");
            }
        }

        long _id;
        [Column(Name = "id", IsPrimaryKey = true)]
        public long Id
        {
            get
            {
                return _id;
            }
            set
            {
                RaisePropertyChanging("Id");
                _id = value;
                RaisePropertyChanged("Id");
            }
        }

        DateTime _createdTime;
        [Column(Name = "created_time")]
        public DateTime CreatedTime
        {
            get
            {
                return _createdTime;
            }
            set
            {
                RaisePropertyChanging("CreatedTime");
                _createdTime = value;
                RaisePropertyChanged("CreatedTime");
            }
        }

        long _timestamp;
        [Column(Name = "timestamp")]
        public long Timestamp
        {
            get
            {
                return _timestamp;
            }
            set
            {
                RaisePropertyChanging("Timestamp");
                _timestamp = value;
                RaisePropertyChanged("Timestamp");
            }
        }

        string _text;
        [Column(Name = "text")]
        public string Text
        {
            get
            {
                return _text;
            }
            set
            {
                RaisePropertyChanging("Text");
                _text = value;
                RaisePropertyChanged("Text");
            }
        }

        string _source;
        [Column(Name = "source")]
        public string Source
        {
            get
            {
                return _source;
            }
            set
            {
                RaisePropertyChanging("Source");
                _source = value;
                RaisePropertyChanged("Source");
            }
        }

        bool _favorited;
        [Column(Name = "is_favorited")]
        public bool Favorited
        {
            get
            {
                return _favorited;
            }
            set
            {
                RaisePropertyChanging("Favorited");
                _favorited = value;
                RaisePropertyChanged("Favorited");
            }
        }

        bool _tuncated;
        [Column(Name = "is_tuncated")]
        public bool Truncated
        {
            get
            {
                return _tuncated;
            }
            set
            {
                RaisePropertyChanging("Truncated");
                _tuncated = value;
                RaisePropertyChanged("Truncated");
            }
        }

        string _replyToStatusId;
        [Column(Name = "reply_to_status_id")]
        public string ReplyToStatusId
        {
            get
            {
                return _replyToStatusId;
            }
            set
            {
                RaisePropertyChanging("ReplyToStatusId");
                _replyToStatusId = value;
                RaisePropertyChanged("ReplyToStatusId");
            }
        }

        string _replyToUserId;
        [Column(Name = "reply_to_user_id")]
        public string ReplyToUserId
        {
            get
            {
                return _replyToUserId;
            }
            set
            {
                RaisePropertyChanging("ReplyToUserId");
                _replyToUserId = value;
                RaisePropertyChanged("ReplyToUserId");
            }
        }

        string _replyToScreenName;
        [Column(Name = "reply_to_screen_name")]
        public string ReplyToScreenName
        {
            get
            {
                return _replyToScreenName;
            }
            set
            {
                RaisePropertyChanging("ReplyToScreenName");
                _replyToScreenName = value;
                RaisePropertyChanged("ReplyToScreenName");
            }
        }

        string _thumbnailPic;
        [Column(Name = "thumbnail_pic")]
        public string ThumbnailPic
        {
            get
            {
                return _thumbnailPic;
            }
            set
            {
                RaisePropertyChanging("ThumbnailPic");
                _thumbnailPic = value;
                RaisePropertyChanged("ThumbnailPic");
            }
        }

        string _bmiddlePic;
        [Column(Name = "bmiddle_pic")]
        public string BmiddlePic
        {
            get
            {
                return _bmiddlePic;
            }
            set
            {
                RaisePropertyChanging("BmiddlePic");
                _bmiddlePic = value;
                RaisePropertyChanged("BmiddlePic");
            }
        }

        string _originalPic;
        [Column(Name = "original_pic")]
        public string OriginalPic
        {
            get
            {
                return _originalPic;
            }
            set
            {
                RaisePropertyChanging("OriginalPic");
                _originalPic = value;
                RaisePropertyChanged("OriginalPic");
            }
        }

        [Column(Name = "user_account_id")]
        int _userAccountID;
        [Column(Name = "user_account_name")]
        string _userAccountName;
        EntityRef<SNSUser> _user;
        [Association(Name = "fk_user_status", IsForeignKey = true, ThisKey = "_userAccountID,_userAccountName", OtherKey = "AccountID,AccountName")]
        public SNSUser User
        {
            get
            {
                return _user.Entity;
            }
            set
            {
                RaisePropertyChanging("User");
                _user.Entity = value;
                if (value != null)
                {
                    _userAccountID = value.AccountID;
                    _userAccountName = value.AccountName;
                }
                RaisePropertyChanged("User");
            }
        }

        [Column(Name = "status_id")]
        long _statusId;
        EntityRef<SNSStatus> _retweetedStatus;
        [Association(Name = "fk_status_status", ThisKey = "_accountID,Id", OtherKey = "_accountID,_statusId")]
        public SNSStatus RetweetedStatus
        {
            get
            {
                return _retweetedStatus.Entity;
            }
            set
            {
                RaisePropertyChanging("RetweetedStatus");
                _retweetedStatus.Entity = value;
                if (value != null)
                {
                    _statusId = value.Id;
                }
                RaisePropertyChanged("RetweetedStatus");
            }
        }

        EntityRef<GeoInfo> _geoInfo;
        [Association(Name = "fk_geo_status", ThisKey = "_accountID,Id", OtherKey = "AccountId,StatusId")]
        public GeoInfo GeoInfo
        {
            get
            {
                return _geoInfo.Entity;
            }
            set
            {
                RaisePropertyChanging("GeoInfo");
                _geoInfo.Entity = value;
                if (value != null)
                {
                    value.AccountId = _accountID;
                    value.StatusId = _id;
                }
                RaisePropertyChanged("GeoInfo");
            }
        }

        SNSProviderType _provider;
        [Column(Name = "sp_type")]
        public SNSProviderType Provider
        {
            get
            {
                return _provider;
            }
            set
            {
                RaisePropertyChanging("Provider");
                _provider = value;
                RaisePropertyChanged("Provider");
            }
        }

        StatusType _type;
        [Column(Name = "status_type")]
        public StatusType Type
        {
            get
            {
                return _type;
            }
            set
            {
                RaisePropertyChanging("Type");
                _type = value;
                RaisePropertyChanged("Type");
            }
        }

        int _repostCount;
        [Column(Name = "repost_count")]
        public int RepostCount
        {
            get
            {
                return _repostCount;
            }
            set
            {
                RaisePropertyChanging("RepostCount");
                _repostCount = value;
                RaisePropertyChanged("RepostCount");
            }
        }

        int _commentCount;
        [Column(Name = "comment_count")]
        public int CommentCount
        {
            get
            {
                return _commentCount;
            }
            set
            {
                RaisePropertyChanging("CommentCount");
                _commentCount = value;
                RaisePropertyChanged("CommentCount");
            }
        }

        string _prefix;
        [Column(Name = "prefix")]
        public string Prefix
        {
            get
            {
                return _prefix;
            }
            set
            {
                RaisePropertyChanging("Prefix");
                _prefix = value;
                RaisePropertyChanged("Prefix");
            }
        }

        List<SNSStatus> _comments;
        public List<SNSStatus> Comments
        {
            get { return _comments; }
            set
            {
                RaisePropertyChanging("Comments");
                _comments = value;
                RaisePropertyChanged("Comments");
            }
        }

        int _page;

        public int Page
        {
            get { return _page; }
            set { _page = value; }
        }

        [Column(IsVersion = true)]
#pragma warning disable 0168, 0169
        private Binary _version;
#pragma warning restore 0168, 0169

        public override string ToString()
        {
            var s = string.Format(
                "{0}|{1}",
                Account != null ? Account.ToString() : null,
                Id
                );

            return s;
        }

        #region IEquatable<SNSStatus> Members

        public bool Equals(SNSStatus other)
        {
            var rv = false;

            if (other != null)
            {
                rv = this.Provider == other.Provider && this.Id == other.Id;
            }

            return rv;
        }

        #endregion
    }

    public class SNSStatusComparer : IEqualityComparer<SNSStatus>
    {
        #region IEqualityComparer<SNSStatus> Members

        public bool Equals(SNSStatus x, SNSStatus y)
        {
            if (x != null && y != null)
            {
                return x.Equals(y);
            }
            else
            {
                return false;
            }
        }

        public int GetHashCode(SNSStatus obj)
        {
            var s = obj.ToString();
            var v = s.GetHashCode();

            return v;
        }

        #endregion
    }

    public enum StatusType
    {
        Original,
        Repost,
        Reply,
        Comment,
        DirectMessage,
        Feed,
    }
}
